ng911ok.lib.topology module#

Implements functionality related to topology.yml. Exposes topology_config, which contains the data derived from topology.yml``.

Provides constructors for the following YAML tags (on yaml.SafeLoader):

  • !FieldRole (Scalar -> NG911Field) - Given a field’s role, returns the corresponding field object

  • !DomainName (Scalar -> NG911Domain) - Given a domain’s name, returns the corresponding field object

final class TopologyRule(dataset: str, member1: NG911FeatureClass, rule: str, member2: NG911FeatureClass | None = None)#

Bases: object

Class representing a topology rule specified by the Standards.

classmethod as_df(members_as: Literal['OBJECT', 'ROLE', 'NAME'] = 'OBJECT', rule_as: Literal['DESCRIPTION', 'ETRT'] = 'DESCRIPTION') DataFrame#

Returns all registered topology rules as a DataFrame with three columns: member1, rule, and member2.

The member1 and member2 columns will have the dtype object if members_as is OBJECT or the dtype string[python] if members_as is ROLE (meaning the NG911FeatureClass.role attribute) or NAME (meaning the NG911FeatureClass.name attribute).

The rule column will have the dtype string[python].

Parameters:
  • members_as (Literal["OBJECT", "ROLE", "NAME"]) – How the member should be represented.

  • rule_as (Literal["DESCRIPTION", "ETRT"]) – How the rules should be represented.

Return pd.DataFrame:

The registered topology rules as a DataFrame.

classmethod from_dict(dataset: str, data: _OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict) Self#
add_rule_to_topology(topology_name: str, manager: EnvManager | None = None) Result#

Adds the rule to a topology using arcpy.

as_series(members_as: Literal['OBJECT', 'ROLE', 'NAME'] = 'OBJECT', rule_as: Literal['DESCRIPTION', 'ETRT'] = 'DESCRIPTION') Series#
has_member(feature_class: NG911FeatureClass) bool#

Returns whether a given feature class is a member of the rule.

_registered_rules: ClassVar[list[Self]] = [TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'discrepancyagency_boundary'>, rule='Must Not Overlap (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Have Dangles (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Intersect (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Single Part (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'address_point'>, rule='Must Be Properly Inside (Point-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Inside (Line-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esz_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>)]#

List of instances of this class, which are automatically registered after initialization.

dataset: str#

The name of the feature dataset containing the feature class(es) to which the rule applies.

member1: NG911FeatureClass#

The first member (“origin”) feature class included in the rule.

member2: NG911FeatureClass | None#

The second member (“destination”) feature class included in the rule.

property members: tuple[NG911FeatureClass] | tuple[NG911FeatureClass, NG911FeatureClass]#

Returns a tuple of the member or members of the rule.

property name1: str#

Returns the name of member1.

property name2: str | None#

Returns the name of member2.

rule: str#

The name (from _ESRI_RULE_NAMES) of the topology rule.

property rule_code: str#

Returns the esriTopologyRuleType code for the rule.

See also

_ESRI_RULE_CODES

class _NG911TopologyConfig(exception_field: NG911Field, exception_domain: NG911Domain, required_dataset_topology_name: str, optional_dataset_topology_name: str, required_dataset_rules: FrozenList[TopologyRule], optional_dataset_rules: FrozenList[TopologyRule])#

Bases: YAMLObject

yaml_loader#

alias of SafeLoader

classmethod from_yaml(loader: SafeLoader, node: Node)#

Convert a representation node to a Python object.

enrich_error_df(error_df: DataFrame, members: Collection[DataFrame], fill_na_submit: bool | None = None) DataFrame#

Processes a topology error DataFrame (from the Export Topology Errors geoprocessing tool). Unless it is empty, the returned pandas.DataFrame will have the following columns:

  • Column Name

dtype

  • OriginObjectClassName

string

  • OriginObjectID

Int32

  • DestinationObjectClassName

string

  • DestinationObjectID

Int32

  • RuleType

string

  • RuleDescription

string

  • SHAPE

geometry

  • OriginObjectClassObject

object

  • OriginObjectNGUID

string

  • OriginObjectSubmit

boolean

  • OriginObjectExceptions

object

  • DestinationObjectClassObject

object

  • DestinationObjectNGUID

string

  • DestinationObjectSubmit

boolean

  • DestinationObjectExceptions

object

  • RuleObject

object

  • IsException

boolean

Parameters:
  • error_df – Topology error DataFrame

  • members – All relevant member feature classes as DataFrames

  • fill_na_submit – Value to assume for invalid values of SUBMIT; if None, a ValueError will be raised if any features involved in an error have an invalid or missing value for that attribute; default None

Returns:

Copy of topology error DataFrame with additional columns

get_rule(member1: NG911FeatureClass | NAType | None, rule_code: esriTopologyRuleType | str, member2: NG911FeatureClass | NAType | None = None) TopologyRule | None#

Searches through the known rules for a rule matching the arguments and returns it. Returns None if no rule is found.

Parameters:
  • member1 (NG911FeatureClass | NAType | None) – Feature class representing the first member

  • rule_code (esriTopologyRuleType | str) – The string code (e.g., esriTRTLineNoDangles), the string description (e.g., “Must Not Have Dangles (Line)”), or the esriTopologyRuleType instance representing the rule

  • member2 (NG911FeatureClass | NAType | None) – Feature class representing the second member, or None (or pandas.NA, which will be treated the same as None) if not applicable; default None

Returns:

The rule matching the arguments, or None if no such rule could be found

Return type:

TopologyRule | None

_dangle_exc = frozenset({'esriTRTLineNoDangles'})#
_inside_exc = frozenset({'esriTRTLineInsideArea', 'esriTRTPointProperlyInsideArea'})#
address_point_allowed_values: ClassVar[frozenset[LiteralString]] = frozenset({'INSIDE_EXCEPTION', 'NO_EXCEPTION'})#
exception_domain: NG911Domain#
exception_field: NG911Field#
exception_mapping: ClassVar[FrozenDict[LiteralString, frozenset[str]]] = FrozenDict({'DANGLE_EXCEPTION': frozenset({'esriTRTLineNoDangles'}), 'INSIDE_EXCEPTION': frozenset({'esriTRTPointProperlyInsideArea', 'esriTRTLineInsideArea'}), 'BOTH_EXCEPTION': frozenset({'esriTRTPointProperlyInsideArea', 'esriTRTLineNoDangles', 'esriTRTLineInsideArea'}), 'NO_EXCEPTION': frozenset()})#
property optional_dataset_members: frozenset[NG911FeatureClass]#

Returns a frozenset with all NG911FeatureClass objects that are involved in self.optional_dataset_rules.

optional_dataset_rules: FrozenList[TopologyRule]#
optional_dataset_topology_name: str#
property required_dataset_members: frozenset[NG911FeatureClass]#

Returns a frozenset with all NG911FeatureClass objects that are involved in self.required_dataset_rules.

required_dataset_rules: FrozenList[TopologyRule]#
required_dataset_topology_name: str#
yaml_tag = '!TopologyConfig'#
class _OneMemberTopologyRuleDict#

Bases: TypedDict

member: str#
rule: str#
class _TopologyConfigDict#

Bases: TypedDict

exception_domain: NG911Domain#
exception_field: NG911Field#
optional_dataset_rules: NotRequired[list[_OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict]]#
optional_dataset_topology_name: str#
required_dataset_rules: list[_OneMemberTopologyRuleDict | _TwoMemberTopologyRuleDict]#
required_dataset_topology_name: str#
class _TwoMemberTopologyRuleDict#

Bases: TypedDict

member1: str#
member2: str#
rule: str#
_construct_domain_from_name(loader: SafeLoader, node: Node) NG911Domain#
_construct_field_from_role(loader: SafeLoader, node: Node) NG911Field#
_ESRI_RULE_CODES: Final[frozenset[str]] = frozenset({'esriTRTAreaAreaCoverEachOther', 'esriTRTAreaBoundaryCoveredByAreaBoundary', 'esriTRTAreaBoundaryCoveredByLine', 'esriTRTAreaContainOnePoint', 'esriTRTAreaContainPoint', 'esriTRTAreaCoveredByArea', 'esriTRTAreaCoveredByAreaClass', 'esriTRTAreaNoGaps', 'esriTRTAreaNoOverlap', 'esriTRTAreaNoOverlapArea', 'esriTRTLineCoveredByAreaBoundary', 'esriTRTLineCoveredByLineClass', 'esriTRTLineEndpointCoveredByPoint', 'esriTRTLineInsideArea', 'esriTRTLineNoDangles', 'esriTRTLineNoIntersectLine', 'esriTRTLineNoIntersectOrInteriorTouch', 'esriTRTLineNoIntersectOrInteriorTouchLine', 'esriTRTLineNoIntersection', 'esriTRTLineNoMultipart', 'esriTRTLineNoOverlap', 'esriTRTLineNoOverlapLine', 'esriTRTLineNoPseudos', 'esriTRTLineNoSelfIntersect', 'esriTRTLineNoSelfOverlap', 'esriTRTPointCoincidePoint', 'esriTRTPointCoveredByAreaBoundary', 'esriTRTPointCoveredByLine', 'esriTRTPointCoveredByLineEndpoint', 'esriTRTPointDisjoint', 'esriTRTPointProperlyInsideArea'})#

Set of Esri topology rule codes, e.g., esriTRTLineNoDangles.

_ESRI_RULE_NAMES: Final[frozenset[str]] = frozenset({'Boundary Must Be Covered By (Area-Line)', 'Boundary Must Be Covered By Boundary Of (Area-Area)', 'Contains One Point (Area-Point)', 'Contains Point (Area-Point)', 'Endpoint Must Be Covered By (Line-Point)', 'Must Be Covered By (Area-Area)', 'Must Be Covered By (Point-Line)', 'Must Be Covered By Boundary Of (Line-Area)', 'Must Be Covered By Boundary Of (Point-Area)', 'Must Be Covered By Endpoint Of (Point-Line)', 'Must Be Covered By Feature Class Of (Area-Area)', 'Must Be Covered By Feature Class Of (Line-Line)', 'Must Be Disjoint (Point)', 'Must Be Inside (Line-Area)', 'Must Be Properly Inside (Point-Area)', 'Must Be Single Part (Line)', 'Must Coincide With (Point-Point)', 'Must Cover Each Other (Area-Area)', 'Must Not Have Dangles (Line)', 'Must Not Have Gaps (Area)', 'Must Not Have Pseudo-Nodes (Line)', 'Must Not Intersect (Line)', 'Must Not Intersect Or Touch Interior (Line)', 'Must Not Intersect With (Line-Line)', 'Must Not Intersect or Touch Interior With (Line-Line)', 'Must Not Overlap (Area)', 'Must Not Overlap (Line)', 'Must Not Overlap With (Area-Area)', 'Must Not Overlap With (Line-Line)', 'Must Not Self-Intersect (Line)', 'Must Not Self-Overlap (Line)'})#

Set of Esri topology rule names, e.g., Must Not Have Dangles (Line).

_ODS: Final[str] = 'OptionalLayers'#

Name of the optional feature dataset.

_RDS: Final[str] = 'NG911'#

Name of the required feature dataset.

_SUBMIT: Final[str] = 'SUBMIT'#

Name of the SUBMIT field.

_TOPOEXCEPT: Final[str] = 'TopoExcept'#

Name of the TopoExcept field.

_TOPOLOGY_YAML_PATH: Final[Path] = WindowsPath('G:/ArcGIS/Project Files/NG911/NG911_Pro/NG911-Pro/topology.yml')#

Path to topology.yml.

topology_config: _NG911TopologyConfig = _NG911TopologyConfig(exception_field=NG911Field(role='topoexcept', name='TopoExcept', type='String', priority='M', length=20, domain=<NG911Domain 'TOPOEXCEPT' [4 Entries]>, fill_value='NO_EXCEPTION'), exception_domain=<NG911Domain 'TOPOEXCEPT' [4 Entries]>, required_dataset_topology_name='NG911_Topology', optional_dataset_topology_name='OptionalLayers_Topology', required_dataset_rules=FrozenList((TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'discrepancyagency_boundary'>, rule='Must Not Overlap (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Not Have Gaps (Area)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Have Dangles (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Overlap (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Not Self-Intersect (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Single Part (Line)', member2=None), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'address_point'>, rule='Must Be Properly Inside (Point-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'road_centerline'>, rule='Must Be Inside (Line-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_ems_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_fire_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esb_law_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'esz_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>), TopologyRule(dataset='NG911', member1=<NG911FeatureClass 'psap_boundary'>, rule='Must Cover Each Other (Area-Area)', member2=<NG911FeatureClass 'discrepancyagency_boundary'>))), optional_dataset_rules=FrozenList(()))#

The single instance of _NG911TopologyConfig that contains the topology rules specified in topology.yml.